/*****************************************************************************
Copyright 2006 Kervin L. Pierre
    EMAIL: otlkcon@adevsoft.com

This file is part of Otlkcon.

Otlkcon is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.

Otlkcon is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Lesser GNU General Public License for more details.

You should have received a copy of the Lesser GNU General Public License
along with Otlkcon; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

*******************************************************************************/

#include "StdAfx.h"
#include "O_IAttach.h"
#include "otlkcon_generic_msgstore.h"

O_IAttach::O_IAttach()
{
    isTransacted = true;
    parent = NULL;
    parentMsg = NULL;
	attachNum = 0;
}

O_IAttach::~O_IAttach()
{
    ;
}

HRESULT O_IAttach::Create(  O_IMessage *par, MAPIUID ig )
{
    HRESULT result = S_OK;
    int propCount = 0;

    result = O_IProp::Create( par->msgstore, ig, otlkcon_iattachment_guid );
    if( result != S_OK )
    {
        OTLKCON_DEBUGBREAK;
    }

    entryID->typeID = MAPI_ATTACH;
    entryID->supportedInterfaces |= OTLKCON_IATTACHMENT_CLASS;
    entryID->primarySupportedInterface = OTLKCON_IATTACHMENT_CLASS;
    entryID->storeInstanceGuid = msgstore->entryID->storeInstanceGuid;

    parent = par->entryID;
    parentMsg = par;

     // Get the attachment number
    // FIXME:  This should be atomic at the SQL layer.
    SizedSPropTagArray(1, attachNumProp);
    ULONG cProps = 0;
    SPropValue defaultProps[10] = {0};
    ULONG currAttachNum = 0;
    LPSPropValue propResult = 0;

    attachNumProp.cValues = 1;
    attachNumProp.aulPropTag[0] = PR_OTLKCON_IMESSAGE_ATTACH_NUM;
    result = par->GetProps( (LPSPropTagArray)&attachNumProp, 
        0, &cProps, &propResult );
    switch( result )
	{
		case MAPI_W_ERRORS_RETURNED:
		case S_OK:			
            if( PROP_ID(propResult[0].ulPropTag) 
                            == PROP_ID(PR_OTLKCON_IMESSAGE_ATTACH_NUM) )
            {
                if( PROP_TYPE(propResult[0].ulPropTag) == PT_LONG )
                {
                    currAttachNum = propResult[0].Value.l;
                }  
            }

			break;

		default:
			//Error condition
            OTLKCON_DEBUGBREAK;
            result = E_FAIL;
            goto create_end;
    }

    // Set the manatory properties.
    defaultProps[propCount].ulPropTag = PR_OBJECT_TYPE;
    defaultProps[propCount++].Value.l = MAPI_ATTACH ;

    defaultProps[propCount].ulPropTag = PR_ATTACH_METHOD;
    defaultProps[propCount++].Value.l = NO_ATTACHMENT ;

    defaultProps[propCount].ulPropTag = PR_RENDERING_POSITION;
    defaultProps[propCount++].Value.l = 1 ;

    // FIXME:  We should doublecheck that this attachment number
    //         has not already been used.
    defaultProps[propCount].ulPropTag = PR_ATTACH_NUM;
    defaultProps[propCount++].Value.l = ++currAttachNum ;
	attachNum = currAttachNum;

	defaultProps[propCount].ulPropTag = PR_INSTANCE_KEY;
	defaultProps[propCount].Value.bin.cb = sizeof(O_ENTRYID) ;
	defaultProps[propCount++].Value.bin.lpb = (LPBYTE)entryID ;

    result = _IntSetProps(propCount, (LPSPropValue)&defaultProps, NULL );

    // Should we SaveChanges() ?
    //result = attach->SaveChanges(0);

    // Update the ATTACH_NUM property
    defaultProps[0].ulPropTag = PR_OTLKCON_IMESSAGE_ATTACH_NUM;
    defaultProps[0].Value.l   = currAttachNum ;

    result = par->_IntSetProps(1, (LPSPropValue)&defaultProps, NULL );

create_end:
    return result;
}

HRESULT O_IAttach::Load( O_ENTRYID *eid )
{
    HRESULT result = S_OK;

    return result;
}

STDMETHODIMP O_IAttach::SaveChanges( ULONG ulFlags )
{
    HRESULT result = S_OK;

    parentMsg->unsavedAttachments.push_back(this);

	//Update attachments table snapshot
	result = parentMsg->attachmentTable->HrUpdateObjectRow(UPDATE_SNAPSHOT_ONLY, this);

    return result;
}

STDMETHODIMP O_IAttach::_IntSaveChanges( ULONG ulFlags )
{
    HRESULT result = S_OK;

	result = O_IProp::SaveChanges(ulFlags);
	
	//So far we using that code because SaveAttachments is broken
	if(SUCCEEDED(result))
	{
		//Update attachments table permanently
		result = parentMsg->attachmentTable->HrUpdateObjectRow(0, this);
	} // if
/*
    SizedSPropTagArray(10, attachProps);
    ULONG currAttachNum = 0;
    ULONG currRenderingPosition = 0;
    ULONG currAttachMethod = 0;
    SPropValue defaultProps[20] = {0};
    LPSPropValue propResult = 0;
    ULONG propCount = 0;
    ULONG cProps = 0;
    SRow row = {0};
    SYSTEMTIME currSysTime;
    FILETIME currFileTime;

    GetSystemTime(&currSysTime);
    SystemTimeToFileTime(&currSysTime, &currFileTime);

    attachProps.cValues = 3;
    attachProps.aulPropTag[0] = PR_ATTACH_NUM;
    attachProps.aulPropTag[1] = PR_RENDERING_POSITION;
    attachProps.aulPropTag[2] = PR_ATTACH_METHOD;
    result = _IntGetProps( (LPSPropTagArray)&attachProps, 
        0, &cProps, &propResult );
    switch( result )
	{
		case MAPI_W_ERRORS_RETURNED:
		case S_OK:			
            if( PROP_ID(propResult[0].ulPropTag) 
                            == PROP_ID(PR_ATTACH_NUM) )
            {
                if( PROP_TYPE(propResult[0].ulPropTag) == PT_LONG )
                {
                    currAttachNum = propResult[0].Value.l;
                }  
            }
            if( PROP_ID(propResult[1].ulPropTag) 
                            == PROP_ID(PR_RENDERING_POSITION) )
            {
                if( PROP_TYPE(propResult[0].ulPropTag) == PT_LONG )
                {
                    currRenderingPosition = propResult[0].Value.l;
                }  
            }
            if( PROP_ID(propResult[2].ulPropTag) 
                            == PROP_ID(PR_ATTACH_METHOD) )
            {
                if( PROP_TYPE(propResult[0].ulPropTag) == PT_LONG )
                {
                    currAttachMethod = propResult[0].Value.l;
                }  
            }

			break;

		default:
			//Error condition
            OTLKCON_DEBUGBREAK;
            result = E_FAIL;
            goto savechanges_end;
    }

    propCount = 0;
    defaultProps[propCount].ulPropTag = PR_INSTANCE_KEY;
    defaultProps[propCount].Value.bin.cb = sizeof(O_ENTRYID);
    defaultProps[propCount++].Value.bin.lpb = (LPBYTE)(entryID);

    defaultProps[propCount].ulPropTag = PR_ATTACH_NUM;
    defaultProps[propCount++].Value.l = currAttachNum;

    defaultProps[propCount].ulPropTag = PR_RECORD_KEY;
    defaultProps[propCount].Value.bin.cb = sizeof(O_ENTRYID);
    defaultProps[propCount++].Value.bin.lpb = (LPBYTE)(entryID);

    defaultProps[propCount].ulPropTag = PR_RENDERING_POSITION;
    defaultProps[propCount++].Value.l = currRenderingPosition;

    defaultProps[propCount].ulPropTag = PR_ATTACH_METHOD;
    defaultProps[propCount++].Value.l = currAttachMethod;

    defaultProps[propCount].ulPropTag = PR_CREATION_TIME;
    defaultProps[propCount++].Value.ft =   currFileTime;

    defaultProps[propCount].ulPropTag = PR_LAST_MODIFICATION_TIME;
    defaultProps[propCount++].Value.ft =   currFileTime;

    row.cValues = propCount;
    row.lpProps = (LPSPropValue)&defaultProps;
    result = parentMsg->m_lpAttachmentsSnapShot->HrModifyRow( &row );
*/

//savechanges_end:
    return result;
}

STDMETHODIMP O_IAttach::SetProps(
	ULONG cValues,
	LPSPropValue lpPropArray,
	LPSPropProblemArray *lppProblems)
{
	HRESULT hResult = S_OK;
	hResult = O_IProp::SetProps(
		cValues,
		lpPropArray,
		lppProblems);
	return hResult;
}

STDMETHODIMP O_IAttach::GetProps(
	LPSPropTagArray lpPropTagArray,
	ULONG        ulFlags,
	ULONG        *lpcValues,
	LPSPropValue *lppPropArray)
{
	HRESULT hResult = S_OK;
	hResult = O_IProp::GetProps(
		lpPropTagArray,
		ulFlags,
		lpcValues,
		lppPropArray);
	return hResult;
}

HRESULT O_IAttach::CreateEntryID( O_ENTRYID *eid, const MAPIUID* sg, MAPIUID ig)
{
	HRESULT hResult = E_INVALIDARG;
	if(NULL != eid)
	{
		hResult = O_IProp::CreateEntryID(eid, sg, ig, otlkcon_iattachment_guid);
		if(SUCCEEDED(hResult))
		{
			eid->typeID = MAPI_ATTACH;
			eid->supportedInterfaces |= OTLKCON_IATTACHMENT_CLASS;
            eid->primarySupportedInterface = OTLKCON_IATTACHMENT_CLASS;
		} // if
	} // if
	return hResult;
}
